package kobetool.dshowwrapper;

import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.filechooser.FileFilter;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;

public class Test extends JFrame {

    private JComboBox videoSize = new JComboBox(new String[]{"none", "320 x 240", "640 x 480", "800 x 600"});
    private JComboBox videoFormat = new JComboBox(new String[]{"none", "I420", "RGB24", "YUY2"});
    private JCheckBox hFlip = new JCheckBox("Flip Horizontal");

    JTabbedPane tabPane = new JTabbedPane();

    Action play = new AbstractAction("Play") {
        public void actionPerformed(ActionEvent e) {
            CaptureDevice device = (CaptureDevice) tabPane.getSelectedComponent();
            if(device==null) return;

            GUID guid = null;
            int width = 0, height = 0;
            switch(videoFormat.getSelectedIndex()) {
                case 1:
                    guid = GUID.I420;
                    break;
                case 2:
                    guid = GUID.RGB24;
                    break;
                case 3:
                    guid = GUID.YUYV;
                    break;
            }
            switch(videoSize.getSelectedIndex()) {
                case 1:
                    width = 320;
                    height = 240;
                    break;
                case 2:
                    width = 640;
                    height = 480;
                    break;
                case 3:
                    width = 800;
                    height = 600;
                    break;
            }

            VideoFormat vf = null;
            if(guid==null) {
                if(width != 0 || height != 0) {
                    vf = new VideoFormat(width, height);
                }
            } else {
                if(width !=0 || height!=0) {
                    vf = new VideoFormat(width, height, guid);
                } else {
                    vf = new VideoFormat(guid);
                }
            }
            if(!device.start(vf, hFlip.isSelected())) {
                JOptionPane.showMessageDialog(Test.this, "The Device does not support the format.");
            }
        }
    };

    Action stop = new AbstractAction("Stop") {
        public void actionPerformed(ActionEvent e) {
            CaptureDevice device = (CaptureDevice) tabPane.getSelectedComponent();
            if(device==null) return;
            device.stop();
            device.repaint();
        }
    };

    Action grab = new AbstractAction("grab") {
        public void actionPerformed(ActionEvent e) {
            CaptureDevice device = (CaptureDevice) tabPane.getSelectedComponent();
            if(device==null) return;
            VideoFormat fmt = device.getFormat();
            if(fmt==null) return;
            if(!fmt.getSubType().equals(GUID.RGB24)) {
                JOptionPane.showMessageDialog(Test.this, "Can only grab rgb24 image.");
                return;
            }
            ByteBuffer buf = device.grab(null);
            BufferedImage img = new BufferedImage(fmt.getWidth(), fmt.getHeight(), BufferedImage.TYPE_3BYTE_BGR);
            byte[] data = ((DataBufferByte)img.getRaster().getDataBuffer()).getData();
            buf.rewind();
            for(int i=img.getWidth()*(img.getHeight()-1)*3; i>=0; i-=img.getWidth()*3) {
                buf.get(data, i, img.getWidth()*3);
            }
            JFileChooser fc = new JFileChooser();
            fc.setFileFilter(new FileFilter() {
                public boolean accept(File f) {
                    return f.isDirectory() || f.getName().endsWith(".jpg");
                }

                public String getDescription() {
                    return "jpg file";
                }
            });
            if(fc.showSaveDialog(Test.this) != JFileChooser.APPROVE_OPTION) return;
            File file = fc.getSelectedFile();
            String fn = file.getName().toUpperCase();
            if(!fn.endsWith(".JPG") && !fn.endsWith(".JPEG")) {
                file = new File(file.getAbsolutePath() + ".jpg");
            }

            try {
                ImageIO.write(img, "jpg", file);
            } catch (IOException e1) {
                JOptionPane.showMessageDialog(Test.this, e1.getMessage());
            }
        }
    };
    Test() {
        JToolBar tb = new JToolBar();
        add(tb, BorderLayout.SOUTH);
        tb.add(new JLabel("Video Size: "));
        tb.add(videoSize);
        tb.add(new JLabel("Video Format: "));
        tb.add(videoFormat);
        tb.add(hFlip);
        tb.add(play);
        tb.add(stop);
        tb.add(grab);

        add(tabPane);
        for(final CaptureDevice cd : CaptureDevice.enumDevices()) {
            tabPane.add(cd.getFriendlyName(), cd);
        }

        addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                for(int i=0; i<tabPane.getTabCount(); i++) {
                    CaptureDevice cd = (CaptureDevice) tabPane.getComponentAt(i);
                    cd.destroy();
                }
                System.exit(0);
            }
        });
        setSize(640, 480);
        setLocationRelativeTo(null);
        setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new Test();
            }
        });
    }
}
